/**
 * 
 */
package jp.tkym.labs.store.sql;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


class PreparedStatementCache{
	private PreparedStatementFactory factory;
	private Map<Class<?>, Map<String,  PreparedStatement>> basicMap;

	PreparedStatementCache(Connection connection){
		factory = new PreparedStatementFactory(connection);
		basicMap = new ConcurrentHashMap<Class<?>, Map<String, PreparedStatement>>();
	}
	
	private Map<String, PreparedStatement> basicMap(Class<?> cls){
		Map<String, PreparedStatement> map = basicMap.get(cls);
		if(map == null){
			map = new ConcurrentHashMap<String, PreparedStatement>();
			basicMap.put(cls, map);
		}
		return map;
	}
	
	<T> PreparedStatement getStatement(PreparedStatementType type, Class<T> cls) throws SQLException{
		return getStatement(type, cls, "");
	}
	
	<T> PreparedStatement getStatement(PreparedStatementType type, Class<T> cls, String addition) throws SQLException{
		Map<String, PreparedStatement> clsMap = basicMap(cls);
		PreparedStatement ps = clsMap.get(type.toString()+addition);
		if(ps == null){
			ps = createStatement(type, cls, addition);
			clsMap.put(type.toString()+addition, ps);
		}
		return ps;
	}
	
	private <T> PreparedStatement createStatement(PreparedStatementType type, Class<T> cls, String addition) throws SQLException{
		if(type.equals(PreparedStatementType.KEY))		return factory.key(cls, addition);
		if(type.equals(PreparedStatementType.ENTITY))	return factory.entity(cls, addition);
		if(type.equals(PreparedStatementType.UPDATE)) 	return factory.update(cls);
		if(type.equals(PreparedStatementType.INSERT)) 	return factory.insert(cls);
		if(type.equals(PreparedStatementType.DELETE)) 	return factory.delete(cls);
		if(type.equals(PreparedStatementType.CREATE)) 	return factory.create(cls);
		if(type.equals(PreparedStatementType.DROP)) 	return factory.drop(cls);
		return null;
	}
}